#!/usr/bin/env python
#coding=utf-8
#author=yobin


from google.appengine.ext import webapp
from google.appengine.api import xmpp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
import google.appengine.api.urlfetch
#import google.appengine.api.users as users
import logging
import os
import sys
from models import *
import feedparser
from google.appengine.api import memcache
from google.appengine.api.labs import taskqueue
from settings import gaeaccount

FLAG_HANDLE = False

Bot_usage_str = u'''Usage:\n
            1.types the words "sub [feed_url]" to the bot to begin subscribing to the feed at the specified feed_url ([feed_url]\n
            2.types the words "unsub [feed_url]" to stop subscribing to the feed\n
            3.types the words "ls" to list all you feeds\n
            '''
class MainPage(webapp.RequestHandler):
    def __init__(self, *args, **kwargs):
        pass

    def get(self):
        user_address = gaeaccount
        chat_message_sent = False
        if xmpp.get_presence(user_address):
            msg = u"Someone has sent you a gift on Example.com. To view: http://example.com/gifts/"
            status_code = xmpp.send_message(user_address, Bot_usage_str)
            chat_message_sent = (status_code != xmpp.NO_ERROR)
        if not chat_message_sent:
            pass
            # Send an email message instead...
        #import pdb; pdb.Pdb(stdin=sys.__stdin__, stdout=sys.__stdout__).set_trace()
        return self.response.out.write(Bot_usage_str)

#my cron job
class cronCheckItem(webapp.RequestHandler):   
    def get(self):       
        status = self.getItemStatus()
        
        if status:
            try:
                afeed = Feeditem.gql("WHERE status = 2")[0]
                updated = []
                for feed in Feeditem.gql("WHERE status = 2").fetch(100):
                    feed.status = 0
                    updated.append(feed)
                db.put(updated)            
            except:
                self.setItemStatus(0)
        else:
            try:
                afeed = Feeditem.gql("WHERE status = 0")[0]
                updated = []
                for feed in Feeditem.gql("WHERE status = 0").fetch(100):
                    if xmpp.get_presence(feed.user):#check the user present
                        feed.status = 1

                        pqueue = taskqueue.Queue(name='item')
                        ptask = taskqueue.Task(url='/taskjob/item/',params=dict(user=feed.user,title='',link=feed.link,itemtile=feed.title))
                        pqueue.add(ptask)
                    else:
                        feed.status = 2
                    updated.append(feed) 
                db.put(updated)            
            except:
                self.setItemStatus(1)
                
    def getItemStatus(self):
        keyname = 'Token_Item_States'
        token = Token.get_by_key_name(keyname)        
        if not token:
            token = Token(key_name = keyname,name = keyname)
        return token.status
    
    def setItemStatus(self,flag):
        keyname = 'Token_Item_States'
        token = Token.get_by_key_name(keyname)        
        if not token:
            token = Token(key_name = keyname,name = keyname,status = flag)
        else:
            token.status = flag
        token.put()

class cronjobHandler(webapp.RequestHandler):   
    def get(self):
        status = self.getFeedStatus()
        
        if status:
            try:
                afeed = Rssfeed.gql("WHERE status = 1")[0]
                updated = []
                for feed in Rssfeed.gql("WHERE status = 1").fetch(100):
                    feed.status = 0
                    updated.append(feed)
                db.put(updated)            
            except:
                self.setFeedStatus(0)
        else:
            try:
                afeed = Rssfeed.gql("WHERE status = 0")[0]
                updated = []                
                for feed in Rssfeed.gql("WHERE status = 0").fetch(100):
                    feed.status = 1
                    updated.append(feed)

                    if xmpp.get_presence(feed.user):#check the user present
                        #let task queue to feed rss
                        pqueue = taskqueue.Queue(name='feed')
                        ptask = taskqueue.Task(url='/taskjob/feed/',params=dict(user=feed.user,url=feed.feed))
                        pqueue.add(ptask)
                db.put(updated)            
            except:
                self.setFeedStatus(1)

    def getFeedStatus(self):
        keyname = 'Token_Feed_States'
        token = Token.get_by_key_name(keyname)        
        if not token:
            token = Token(key_name = keyname,name = keyname)
        return token.status
    
    def setFeedStatus(self,flag):
        keyname = 'Token_Feed_States'
        token = Token.get_by_key_name(keyname)        
        if not token:
            token = Token(key_name = keyname,name = keyname,status = flag)
        else:
            token.status = flag
        token.put()
        
class Task_feed(webapp.RequestHandler):
    def post(self):
        url   = self.request.get('url',None)
        user = self.request.get('user',None)
        if url and user:
            self.feedparser(user,url)        
        
    def feedparser(self,user,feedurl):
        if xmpp.get_presence(user):#check the user present        
            try:
                import feedparser
                d = feedparser.parse(feedurl)        
                feedtitle = d.feed.title             
                for item in d['items']:       
                    link = item['link']
                    keyname = 'Feeditem_%s_%s' % (user,link)
                    rssitem = Feeditem.get_by_key_name(keyname)
                    if not rssitem:
                        try:
                            itemtile = item['title'].decode('cp936','ignore').encode('utf-8')
                        except:
                            itemtile = item['title']
                        pqueue = taskqueue.Queue(name='item')
                        ptask = taskqueue.Task(url='/taskjob/item/',params=dict(user=user,title=feedtitle,link=link,itemtile=itemtile))
                        pqueue.add(ptask)
            except:
                pass
                
class Task_item(webapp.RequestHandler):
    def post(self):
        title    = self.request.get('title',None)
        user     = self.request.get('user',None)
        link     = self.request.get('link',None)
        itemtile = self.request.get('itemtile',None)
        
        keyname = 'Feeditem_%s_%s' % (user,link)
        rssitem = Feeditem.get_by_key_name(keyname)
        if not rssitem:
            rssitem = Feeditem(key_name = keyname,user=user,title=title,link=link,status = 0)
        
        chat_message_sent = False
        if xmpp.get_presence(user) and rssitem.status == 0:            
            msg = u'''[New feed]:%s, %s\n%s''' % (title,itemtile,link)
            status_code = xmpp.send_message(user, msg)
            chat_message_sent = (status_code != xmpp.NO_ERROR)
            #if chat_message_sent:
            rssitem.status = 1
        rssitem.put()


class XMPPHandler(webapp.RequestHandler):
    def post(self):
        msg = self._message = xmpp.Message(self.request.POST)       
        xfrom = msg.sender
        cmd   = msg.body
        
        try:
            if(self.process_command()):
                return            
        except:
            logging.info('fail')
        return msg.reply(Bot_usage_str)               

    def process_command(self):       
        logging.info('---process_command()---')
        #userid@gmail.com/Talk.v10542CE4EDE
        _from = self._message.sender.split('/')[0]        
        msg   = self._message.body
        
        logging.info(_from)
        logging.info(msg)
        try:
            myset = msg.split(' ')
            cmd   = myset[0]
            para  = myset[1]
        except:
            cmd  = msg
            para = ''
        
        logging.info(cmd)
        logging.info(para)
        
        flag = True
        if cmd == 'sub':
            logging.info('---sub---')
            feed = ''.join(para.split())
            username = 'Rssfeed_%s_%s' % (_from,feed)
            userfeed = Rssfeed.get_by_key_name(username)
            if userfeed:
                self._message.reply(u"you have already sub %s!" % (feed))
            else:
                userfeed = Rssfeed(key_name=str(username),user = str(_from),feed=str(feed))
                userfeed.put()
                self._message.reply(u'%s sub success!' % (feed))
            logging.info('sub ok')
        elif cmd == 'unsub':
            logging.info('---unsub---')
            feed = ''.join(para.split())
            username = 'Rssfeed_%s_%s' % (_from,feed)
            userfeed = Rssfeed.get_by_key_name(username)
            if userfeed:
                userfeed.delete()
                self._message.reply('%s unsub success!' % (feed))  
            else:
                return False
            logging.info('unsub ok')
        elif cmd == 'ls':
            logging.info('---ls---')
            
            myfeed = ''
            qstr = "WHERE user = '%s'" % str(_from)
            feeds = Rssfeed.gql(qstr).fetch(100)            
            for item in feeds:
                myfeed += '%s\n' % str(item.feed)
            
            if len(myfeed) > 0:
                self._message.reply(myfeed)
            else:
                self._message.reply("You've no feed yet!")
            logging.info('ls ok')
        else:
            flag = False
            logging.info('other')
        return flag

app = webapp.WSGIApplication([
    ('/', MainPage),
    ('/_ah/xmpp/message/chat/', XMPPHandler),
    ('/tasks/periodical', cronjobHandler),#cron
    ('/cron/checkitem', cronCheckItem),#cron
    ('/taskjob/feed/', Task_feed),#task
    ('/taskjob/item/', Task_item),#task
], debug=True)

def main():
    run_wsgi_app(app)

if __name__ == '__main__':
    main()